using System.Runtime.CompilerServices;
using UnityEngine;

public static class MathUtils {
	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static float Remap(this float value, float from1, float to1, float from2, float to2) => (value - from1) / (to1 - from1) * (to2 - from2) + from2;

	public static float RotationToCourse(float value) {
		var val = value % 360;
		if ( val < 0 ) {
			val = 360 + val;
		}
		if ( Mathf.Approximately(val, 360) ) {
			val = 0f;
		}
		return val;
	}

	public static (T min, T max) MinMax<T>(T[] array) where T : System.IComparable<T> {
		T min = array[0];
		T max = array[0];
		foreach ( var item in array ) {
			if ( item.CompareTo(min) < 0 ) {
				min = item;
			} else if ( item.CompareTo(max) > 0 ) {
				max = item;
			}
		}
		return (min, max);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static Vector3 RandomVector3(float range) {
		return new Vector3(UnityEngine.Random.Range(-range, range)
				, UnityEngine.Random.Range(-range, range)
				, UnityEngine.Random.Range(-range, range));
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static float Sqr(float value) {
		return value * value;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	static public Vector4 Vector4(this Vector3 v3, float w) {
		Vector4 v4 = (Vector4)v3;
		v4.w = w;
		return v4;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	static public void ClampMin(this ref Vector2Int v, Vector2Int min) {
		if ( v[0] < min[0] ) {
			v[0] = min[0];
		}
		if ( v[1] < min[1] ) {
			v[1] = min[1];
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	static public void ClampMax(this ref Vector2Int v, Vector2Int max) {
		if ( v[0] > max[0] ) {
			v[0] = max[0];
		}
		if ( v[1] > max[1] ) {
			v[1] = max[1];
		}
	}
}